package Avocado.form {
	
	import com.greensock.TweenMax;
	
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.FocusEvent;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.ColorTransform;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFieldType;
	import flash.text.TextFormat;
	
	public class FormArea extends MovieClip {
		
		public var background:Sprite;
		
		private var fieldWidth:Number;
		private var fieldHeight:Number;
		private var textBase:String;
		private var maxChars:Number;
		private var bgColor:uint;
		private var bgOpacity:Number;
		private var rule:RegExp;
		private var replaceTo:String;
		private var errorColor:uint;
		private var errorOpacity:Number;
		private var errorAmount:Number;
		
		private var _lock:Boolean;
		
		private var format:TextFormat;
		public var field:TextField = new TextField;
		
		
		/**
		 * FormArea
		 * 
		 * creates easyly a FormField applicable, returns a movieclip
		 * 
		 * #TODO
		 * transition effects on focus_in / focus_out on a field
		 * 
		 * @_format : TextFormat - the text format of the field
		 * @_fieldWidth : Number - the number in pixels of the width of the field, default 30
		 * @_fieldHeight : Number - the number in pixels of the height of the field, default 30
		 * @_textBase : String - the base text of a field
		 * @_maxChars : Number - the maximu number of existing characthers on the field, default 256
		 * @_bgColor : uint - background color value
		 * @_bgOpacity : Number - the number between 0 and 1 to apply a background opacity
		 * @_rule : RegExp - the regular expression to apply on a field
		 * @_replaceTo : String - the regulas expression mismatches to form a field, affected by the @_maxChars
		 * 
		 * ***/
		public function FormArea(_format:TextFormat, _fieldWidth:Number=30, _fieldHeight:Number=30, _textBase:String='', _maxChars:Number=256, _bgColor:uint=0xBDBEC1, _bgOpacity:Number=1, _rule:RegExp=null, _replaceTo:String=null, _errorColor:uint=0xee0000, _errorOpacity:Number=1, _errorAmount:Number=1) {
			super();
			
			this.format = _format;
			this.fieldWidth = _fieldWidth;
			this.fieldHeight = _fieldHeight;
			this.textBase = _textBase;
			this.bgColor = _bgColor;
			this.bgOpacity = _bgOpacity;
			this.maxChars = _maxChars;
			this.rule = _rule;
			this.replaceTo = _replaceTo;
			this.errorColor = _errorColor;
			this.errorOpacity = _errorOpacity;
			this.errorAmount = _errorAmount;
			
			this.addEventListener(Event.ADDED_TO_STAGE, initThis);
		}
		
		
		/**
		 * setup textfield value and auto validate the text
		 * @_value : String 
		 * ***/
		public function set textValue(_value:String):void{
			field.text = _value;
			validate();
		}
		public function get textValue():String{
			validate();
			return field.text.toString();
		}
		
		
		/**
		 * 
		 * ***/
		private function initThis(e:Event):void{
			this.removeEventListener(Event.ADDED_TO_STAGE, initThis);
			setupBackgorund();
			setupField();
		}

		/**
		 * lock the text filed
		 * ***/
		public function lock():void{
			_lock = true;
			
			field.selectable = false;
			field.type = TextFieldType.DYNAMIC;
			field.removeEventListener(MouseEvent.CLICK, clearField);
			field.removeEventListener(FocusEvent.FOCUS_IN, clearField);
			field.removeEventListener(FocusEvent.FOCUS_OUT, exitField);
			
			field.setSelection(0,0);
		}
		
		/**
		 * unlock the text filed
		 * ***/
		public function unlock():void{
			_lock = false;
			
			field.selectable = true;
			field.type = TextFieldType.INPUT;
			field.addEventListener(MouseEvent.CLICK, clearField);
			field.addEventListener(FocusEvent.FOCUS_IN, clearField);
			field.addEventListener(FocusEvent.FOCUS_OUT, exitField);
		}

		
		
		
		
		
		
		
		
		/**
		 * 
		 * ***/
		private function setupBackgorund():void{
			background = new Sprite;
			background.graphics.beginFill(this.bgColor);
			background.graphics.drawRoundRect(0, 0, fieldWidth, this.fieldHeight, 4, 4);
			background.graphics.endFill();
			background.alpha = this.bgOpacity;
			addChild(background);
		}
		private function updateBackground():void{
			background.graphics.clear();
			background.graphics.beginFill(this.bgColor);
			background.graphics.drawRoundRect(0, 0, this.fieldWidth, this.fieldHeight, 4, 4);
			background.graphics.endFill();
			background.alpha = this.bgOpacity;
		}
		
		
		/**
		 * 
		 * ***/
		private function setupField():void{
			field.width = this.fieldWidth - 6;
			field.height = this.fieldHeight - 6;
			field.text = textBase;
			field.embedFonts = true;
			field.defaultTextFormat = format;
			field.setTextFormat(format);
			field.type = TextFieldType.INPUT;
			field.multiline = true;
			field.wordWrap = true;
			field.x = 3;
			field.y = 3;
			field.maxChars = this.maxChars;
			field.addEventListener(MouseEvent.CLICK, clearField);
			field.addEventListener(FocusEvent.FOCUS_IN, clearField);
			field.addEventListener(FocusEvent.FOCUS_OUT, exitField);
			addChild(field);
			
			updateBackground();

			if (_lock == true)
				this.lock();
		}
		
		
		/**
		 * clear the text filed
		 * ***/
		private function clearField(e:Event=null):void{
			if (field.text == textBase){
				field.text = '';
			} else {
				field.setSelection(0, field.maxChars);	
			}
			TweenMax.to(background, .33, {alpha: bgOpacity, colorTransform:{tint:errorColor, tintAmount: 0}});
		}
		
		/**
		 * run when the user leave the field
		 * ***/
		private function exitField(e:Event=null):void{
			if (field.text == ''){
				field.text = textBase;
			}
			TweenMax.to(background, .33, {alpha: bgOpacity, colorTransform:{tint:errorColor, tintAmount: 0}});
		}
		
		/**
		 * validate the field based on a regular expression
		 * ***/
		public function validate():Boolean{
			var valid:Boolean = new Boolean(false);
			if (rule) {
				if (field.text.toString().search(rule) < 0) {
					TweenMax.to(background, .33, {alpha: errorOpacity, colorTransform:{tint:errorColor, tintAmount: errorAmount}});
				} else {
					if (replaceTo){
						field.text = field.text.toString().replace(rule,replaceTo);
					}
					TweenMax.to(background, .33, {alpha: bgOpacity, colorTransform:{tint:errorColor, tintAmount: 0}});
					valid = true;
				}
			} else {
				valid = true;
			}
			
			if (field.text == this.textBase){
				valid = false;
				TweenMax.to(background, .33, {alpha: errorOpacity, colorTransform:{tint:errorColor, tintAmount: errorAmount}});
			} else {
				valid == true;
				TweenMax.to(background, .33, {alpha: bgOpacity, colorTransform:{tint:errorColor, tintAmount: 0}});
			}

			return valid;
		}
		
	}
}